import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

///Provider是provider包中最基本的提供者widget类型。它可以给包括住的所有widget提供值，但是当该值改变时，并不会更新widget。
main() {
  WidgetsFlutterBinding.ensureInitialized();
  Provider.debugCheckInvalidValueType = null;

  runApp(ChangeNotifierProvider<CounterModel>.value(
    value: CounterModel(), //2
    child: MyApp(),
  ));

  runApp(MultiProvider(providers: [
    ChangeNotifierProvider<CounterModel>(
        create: (context) => CounterModel(), lazy: true),
    //this provider depend on onStart() loaded data, so it need to be execute after onStart()
  ], child: MyApp()));

  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) => CounterModel()),
      ],
      child: MyApp(),
    ),
  );

  runApp(FutureProvider(
    initialData: CounterModel(),
    create: (context) => someAsyncFunctionToGetMyModel(),
    child: MyApp(),
  ));

  runApp(
    Provider(create: (_) => CounterModel(), child: MyApp()),
  );

  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_) => CounterModel()),
      FutureProvider(
        create: (context) => someAsyncFunctionToGetMyModel(),
      ),
      StreamProvider(
          create: (context) => CounterModel().stream,
          initialData: ThemeData.light())
    ],
    child: MyApp(),
  ));
}

Future<CounterModel> someAsyncFunctionToGetMyModel() async {
  //  <--- async function
  await Future.delayed(Duration(seconds: 3));
  return CounterModel();
}

class CounterModel with ChangeNotifier, DiagnosticableTreeMixin {
  final StreamController<int> _countController = StreamController();
  int _count = 0;

  Stream<int> stream;

  CounterModel() {
    stream = _countController.stream.asBroadcastStream();
  }

  int get count => _count;

  void add() {
    _count++;
    notifyListeners();
  }

  /// Makes `Counter` readable inside the devtools by listing all of its properties
  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(IntProperty('count', count));
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'tdy-step',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Demo1(),
    );
  }
}

class Demo1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          Selector<CounterModel, dynamic>(
              selector: (_, store) => store.count,
              builder: (_, data, __) => Text(data.toString())),
          Center(
            child: Text("${Provider.of<CounterModel>(context).count}"), //1
          ),
          InkWell(
            onTap: () {
              var counterModel =
                  Provider.of<CounterModel>(context, listen: false);
              counterModel.add();
            },
            child: Text("Test"),
          )
        ],
      ),
    );
  }
}

class Demo2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(
          //Calls `context.watch` to make [Count] rebuild when [Counter] changes.
          '${context.watch<CounterModel>().count}',
          key: const Key('counterState'),
          style: Theme.of(context).textTheme.headline4),
    );
  }
}

class Demo3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Builder(
        builder: (context) {
          // 获取到provider提供出来的值
          CounterModel _model = Provider.of<CounterModel>(context);
          return Container(
              margin: const EdgeInsets.only(top: 20),
              width: MediaQuery.of(context).size.width,
              padding: const EdgeInsets.all(20),
              alignment: Alignment.center,
              color: Colors.lightBlueAccent,
              child: Text('当前是：${_model.count}'));
        },
      ),
    );
  }
}

class Demo4 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Consumer<CounterModel>(
        // 获取到provider提供出来的值
        builder: (context, model, child) {
          return Container(
            margin: const EdgeInsets.only(top: 20),
            width: MediaQuery.of(context).size.width,
            padding: const EdgeInsets.all(20),
            alignment: Alignment.center,
            color: Colors.lightGreen,
            child: Text(
              '${model.count}',
            ),
          );
        },
      ),
    );
  }
}

class Demo5 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: StreamBuilder(
          stream: Provider.of<CounterModel>(context).stream,
          initialData: 0,
          builder: (context, snapshot) {
            return Center(child: Text("${snapshot.data}"));
          }),
    );
  }
}

class Demo6 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ValueNotifier<int> count = ValueNotifier(0);
    return Container(
      child: ValueListenableProvider.value(
        value: count,
        child: Container(),
      ),
    );
  }
}

class Demo7 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<int>(
      create: (context) => CounterModel().stream,
      initialData: 22,
      // ignore: missing_return
      catchError: (context, error) {
        print(error.toString());
      },
      child: Container(),
    );
  }
}
